package com.kocla.mz.canvasdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by admin on 2017/3/27.
 */

public class CanvasView extends View {
    Paint mPaint;
    Bitmap mBitmap;

    public CanvasView(Context context) {
        this(context, null);
    }

    public CanvasView(Context context, @Nullable AttributeSet attrs) {
        this(context, null, 0);
    }

    public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mPaint.setColor(Color.BLACK);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //http://www.cnblogs.com/mysearchblog/p/5926288.html
        //http://www.cnblogs.com/hwgt/p/5416866.html
//        testTranslate(canvas);
//        canvas.restore();//还原画布
//        canvas.translate(250, 0);//平移
//        testRotate(canvas);
//        canvas.translate(-250, 0);//还原
//        canvas.translate(0, 250);
//        testScale(canvas);
//        canvas.translate(0, 250);
//        testSkew(canvas);
        testSaveAndRestore(canvas);
    }

    /**
     * translate(平移)
     * 方法：translate(float dx, float dy)
     * <p>
     * 解析：平移，将画布的坐标原点向左右方向移动x，向上下方向移动y，canvas默认位置在(0,0)
     * <p>
     * 参数：dx为水平方向的移动距离，dy为垂直方向的移动距离
     *
     * @param canvas canvas
     */
    private void testTranslate(Canvas canvas) {
        for (int i = 0; i < 5; i++) {
            canvas.drawCircle(30, 30, 30, mPaint);
            canvas.translate(50, 50);//每次平移画布(50,50)
        }
    }

    /**
     * rotate(旋转,rotate()旋转的是整个坐标轴,当x/y轴方向反向后再平移，例如x反向后平移100，就是网左边100，这点请注意)
     * 方法：rotate(float degrees) / rotate(float degrees, float px, float py)
     * <p>
     * 解析：围绕坐标原点(这里应该是画布原点,经过旋转后的画布原点不等于view的坐标原点,这点请注意)旋转degrees度，值为正顺时针
     * <p>
     * 参数：degrees为旋转角度，px和py为指定旋转的中心点坐标(px,py)
     *
     * @param canvas canvas
     */
    private void testRotate(Canvas canvas) {
        Rect rect = new Rect(50, 0, 150, 50);
        canvas.translate(200, 200);//平移：图像的中心点
        for (int i = 0; i < 36; i++) {
            canvas.drawRect(rect, mPaint);
            canvas.rotate(10);
            //canvas.rotate(10,200,200);以(200,200)为旋转点
        }
        canvas.translate(-200, -200);//还原
    }

    /**
     * scale(缩放)
     * 方法：scale(float sx, float sy) / scale(float sx, float sy, float px, float py)
     * <p>
     * 解析：对画布进行缩放
     * <p>
     * 参数：sx为水平方向缩放比例，sy为竖直方向的缩放比例，px和py我也不知道，小数为缩小， 整数为放大
     *
     * @param canvas canvas
     */
    private void testScale(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.scale(0.8f, 0.8f);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.scale(0.8f, 0.8f);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
    }

    /**
     * skew(倾斜)
     * 方法：skew(float sx, float sy)
     * <p>
     * 解析：倾斜，也可以译作斜切，扭曲
     * <p>
     * 参数：sx为x轴方向上倾斜的对应角度，sy为y轴方向上倾斜的对应角度，两个值都是tan值哦！ 都是tan值！都是tan值！比如要在x轴方向上倾斜60度，那么小数值对应:tan 60 = 根号3 = 1.732！
     *
     * @param canvas canvas
     */
    private void testSkew(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.translate(200, 200);
        canvas.skew(0.2f, -0.8f);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
    }

    /**
     * http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0304/960.html
     * ❑ save：用来保存Canvas的状态。save之后，可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。
     * <p>
     * ❑ restore：用来恢复Canvas<b>之前保存</b>的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
     * <p>
     * save1()-->save2()-->save3()-->save4()-->restore4():   save3()后的canvas
     * save1()-->save2()-->save3()-->save4()-->restore4()-->restore3():   save2()后的canvas
     * save1()-->save2()-->save3()-->save4()-->restore4()-->restore2()-->restore1():   save1()后的canvas
     *
     * @param canvas canvas
     */
    private void testSaveAndRestore(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.save();
        //
        canvas.translate(200, 0);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.save();
        //
        canvas.translate(200, 0);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.save();
        //
        canvas.translate(200, 0);
        //http://blog.csdn.net/zly921112/article/details/50401976
        Rect rect = new Rect(0, 0, 500, 20);//画一个矩形
        mPaint.setTextSize(20);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setTextAlign(Paint.Align.LEFT);
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
        float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
        int baseLineY = (int) (rect.centerY() - top / 2 - bottom / 2);//基线中间点的y轴计算公式
        canvas.drawText("你好世界1", rect.left, baseLineY, mPaint);
        //
        //canvas.restore();//
        //canvas.restore();
        //canvas.restore();
        canvas.restoreToCount(1);
        canvas.drawText("你好世界2", rect.left, baseLineY, mPaint);
    }
}
